package cn.bonoon.services.plugins;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bonoon.core.plugins.LoginRecordService;
import cn.bonoon.entities.AccountEntity;
import cn.bonoon.entities.LoginEntity;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.support.services.AbstractSearchService;

@Service
@Transactional(readOnly = true)
public class LoginRecordServiceImpl extends AbstractSearchService<LoginEntity> implements LoginRecordService {

	@Override
	@Transactional
	public void login(IOperator user, String info, String ip, boolean success, String sessionId) {
		
		Long uid = user.getId();
		
		AccountEntity ae = entityManager.find(AccountEntity.class, uid);
		if (null == ae)
			return;

		internalLogin(info, ip, success, sessionId, ae);
	}
	
	@Override
	@Transactional
	public void login(String lname, String info, String ip, boolean success, String sessionId) {
		AccountEntity ae = null;
		String ql = "select x from AccountEntity x where x.deleted=false and x.loginName=?";
		 ae = __first(AccountEntity.class, ql, lname);
		if(null != ae){
			internalLogin(info, ip, success, sessionId, ae);
		}else if(!success){
			LoginEntity entity = new LoginEntity();
			entity.setLoginName(lname);
			entity.setUserName("没有该用户");
			
			entity.setLoginsuccess(success);
			entity.setLoginAt(new Date());
			entity.setLoginIp(ip);
			entity.setAdditionalInfo("没有该用户");
			entity.setSessionId(sessionId);
			entityManager.persist(entity);
		}
	}

	private void internalLogin(String info, String ip, boolean success,String sessionId, AccountEntity ae) {
		LoginEntity entity = new LoginEntity();
		entity.setLoginName(ae.getLoginName());
		entity.setUserName(ae.getName());
		entity.setOwnerId(ae.getOwnerId());
		entity.setCreatorId(ae.getId());
		
		entity.setLoginsuccess(success);
		entity.setLoginAt(new Date());
		entity.setLoginIp(ip);
		entity.setAdditionalInfo(info);
		entity.setSessionId(sessionId);

		if(success){
			ae.setHasLogon(true);
			ae.setLogonMessage("登录成功");
			ae.setTryLoginCount(0);
		}else{
			ae.setLogonMessage("登录失败");
			if(ae.getTryLoginCount() == null)ae.setTryLoginCount(1);
			else ae.setTryLoginCount(ae.getTryLoginCount() + 1);
		}
		
		ae.setLastLogonAt(ae.getCurrentLogonAt());
		ae.setLastLogonIp(ae.getCurrentLogonIp());

		ae.setCurrentLogonAt(entity.getLoginAt());
		ae.setCurrentLogonIp(entity.getLoginIp());
		
		entityManager.persist(entity);
		entityManager.merge(ae);
	}

	@Override
	@Transactional
	public void logout(Long id) {
//		String hql = "update LoginEntity set logoutAt=:logoutAt where loginsuccess=true and id=:id";
//		entityManager.createQuery(hql).setParameter("logoutAt", new Date()).setParameter("id", id).executeUpdate();
		//entityManager.flush();
	}

	@Override
	@Transactional
	public void logout(String name) {
//		String hql = "update LoginEntity set logoutAt=:logoutAt where loginsuccess=true and loginName=:loginName";
//		entityManager.createQuery(hql).setParameter("logoutAt", new Date()).setParameter("loginName", name).executeUpdate();
		//entityManager.flush();
	}
	
	@Override
	@Transactional
	public void logouWithSessionId(String id) {
		entityManager.createQuery("update LoginEntity set logoutAt=? where sessionId=?")
			.setParameter(1, new Date())
			.setParameter(2, id)
			.executeUpdate();
	}

//	@Override
//	public List<LoginEntity> activityLogin() {
//		Calendar cal = Calendar.getInstance();
//		// 24小时内的登录情况
//		cal.add(Calendar.DAY_OF_MONTH, -1);
//		String hql = "select x from LoginEntity x where x.loginsuccess=true and logoutAt=null and loginAt>=?";
//		return __list(LoginEntity.class, hql, cal.getTime());
//	}

	@Override
	public List<LoginEntity> activities() {
		String hql = "from LoginEntity x where x.id in (select max(y.id) from LoginEntity y where y.loginsuccess=true and y.logoutAt is null group by y.loginName) order by x.loginAt desc";
		return __list(LoginEntity.class, hql);
	}

	@Override
	@Transactional
	public void logoutSessionId(String sessionId) {
		String hql = "update LoginEntity set logoutAt=:logoutAt where loginsuccess=true and sessionId=:sessionId";
		entityManager.createQuery(hql).setParameter("logoutAt", new Date()).setParameter("sessionId", sessionId).executeUpdate();
		entityManager.flush();
	}

	@Override
	@Transactional
	public void allLogout() {
		String hql = "update LoginEntity set logoutAt=:logoutAt where loginsuccess=true and logoutAt is null";
		entityManager.createQuery(hql).setParameter("logoutAt", new Date()).executeUpdate();
	}

	@Override
	public String getSessionId(Long id) {
		String ql = "select x.sessionId from LoginEntity x where x.logoutAt=null and x.id=?";
		return __first(String.class, ql, id);
	}

}
